Vue3 Attributes Binding
In Vue3, when using a child component in the parent component, the properties passed in will be bound to the root element of the child component by default. For example:
<Button
size="small"
@click="onClick"
@focus="onFocus"
@mouseover="onMouseover"> Test </Button>
Child component is as follows:
<template>
<div>
<button>Click me</button>
</div>
</template>
Then, the three events on the Button component will be bound to the div by default, not the button.
Q: If the child component is simple, you can directly enjoy the convenience provided by Vue. If the child component is complex, how to manually prevent default binding?
A: In the script tag of the child component, you need to disable inheritAttrs
, use $attrs
to get all attributes, and use v-bind="$attrs"
on the element where you want to bind the attributes:
<template>
<div>
<button v-bind="$attrs">
Click me
</button>
</div>
</template>
<script>
export default {
inheritAttrs: false,
};
</script>
// ...
Q: If there are many attributes and you want to bind them to more elements, how can you achieve this?
A: You can destructure the context in setup and bind it to the corresponding elements separately.
<template>
<div :size="size">
<button @Click="onClick">
Click me
</button>
</div>
</template>
<script>
export default {
inheritAttrs: false,
setup(props, context) {
const {onClick, onMouseover, onFocus} = context.attrs
return {size, onClick, onMouseover, onFocus}
}
};
</script>
// ...
Too troublesome?
You can also use the ES6 rest operator to bind in batches.
<template>
<div :size="size">
<button v-bind="actions">
Click me
</button>
</div>
</template>
<script>
export default {
inheritAttrs: false,
setup(props, context) {
const {size, ...actions} = context.attrs
return {size, actions}
}
};
</script>
// ...